﻿using IISLogAnalyzer.Common;
using IISLogAnalyzer.DbHelper;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace IISLogAnalyzer
{
    public partial class FormProgress : Form
    {
        private DateTime startTime;
        private bool isRunning = false;
        private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
        // 合并任务列表以便一起等待  
        List<Task> allTasks = new List<Task>();
        FormIISLogAnalyzer mainForm;
        public FormProgress(FormIISLogAnalyzer formIISLogAnalyzer)
        {
            InitializeComponent();
            mainForm = formIISLogAnalyzer;

            // 初始化进度条的最大值  
            progressBarFiles.Maximum = 100;
            progressBarLines.Maximum = 100;
            progressBarDatabase.Maximum = 100;
        }

        #region 计时器
        private void TimerCallback(CancellationToken token)
        {
            startTime = DateTime.Now;
            lbStartTime.Invoke((MethodInvoker)delegate { lbStartTime.Text = "开始：" + startTime.ToString("yyyy 年 MM 月 dd 日 HH:mm:ss"); });

            while (isRunning && !token.IsCancellationRequested)
            {
                lbEndTime.Invoke((MethodInvoker)delegate { lbEndTime.Text = "实时：" + DateTime.Now.ToString("yyyy 年 MM 月 dd 日 HH:mm:ss"); });

                TimeSpan elapsedTime = DateTime.Now.Subtract(startTime);
                UpdateDisplayTime(elapsedTime);

                Thread.Sleep(1000);
            }
        }

        private void UpdateDisplayTime(TimeSpan elapsedTime)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<TimeSpan>(UpdateDisplayTime), elapsedTime);
            }
            else
            {
                DisplayTimeLabel.Text = " 耗时: " + ConvertSecondsToString(elapsedTime.TotalSeconds);
            }
        }

        public static string ConvertSecondsToString(double seconds)
        {
            int days = (int)(seconds / (24 * 60 * 60));
            seconds %= 24 * 60 * 60;
            int hours = (int)(seconds / (60 * 60));
            seconds %= 60 * 60;
            int minutes = (int)(seconds / 60);
            seconds %= 60;

            // 如果秒数需要保留小数，可以使用 ToString 方法格式化输出  
            string formattedSeconds = seconds.ToString("F0"); // F0 表示不保留小数，如果需要保留特定小数位数，可以改为 "F1"、"F2" 等  

            return $"{days} 天 {hours} 小时 {minutes} 分 {formattedSeconds} 秒";
        }

        #endregion

        #region 多线程处理
        /// <summary>
        /// 这是处理线程
        /// </summary>
        /// <param name="listIndex"></param>
        /// <param name="token"></param>
        private void EnqueueDataAsync(int listIndex, CancellationToken token)
        {
            Logger.WriteLog("启动_分析线程_" + listIndex, "启动分析线程_" + listIndex);

            for (int i = 0; i < TraverseDirectoryFiles.distributedLists[listIndex].Count; i++)
            {
                if (token.IsCancellationRequested)
                {
                    break;
                }

                TraverseDirectoryFiles.filePathsCountIindex++;

                // 分析日志并生成SQL语句，然后将它们添加到队列中  
                mainForm.AnalyzeLog(TraverseDirectoryFiles.distributedLists[listIndex][i], token, progressBarLines, lbFile);

                // 更新进度  
                lock (TraverseDirectoryFiles.SyncRoot)// 使用锁来确保线程安全  
                {
                    if (token.IsCancellationRequested)
                    {
                        break;
                    }

                    // 更新进度（进度条的范围是0-100）  
                    int progressPercentage = (int)((double)TraverseDirectoryFiles.filePathsCountIindex / TraverseDirectoryFiles.totalFiles * 100);
                    if (progressPercentage > 100)
                    {
                        progressPercentage = 100;

                        if (TraverseDirectoryFiles.filePathsCountIindex > TraverseDirectoryFiles.totalFiles)
                        {
                            TraverseDirectoryFiles.filePathsCountIindex = TraverseDirectoryFiles.totalFiles;
                        }
                    }

                    progressBarFiles.Invoke((MethodInvoker)delegate { progressBarFiles.Value = progressPercentage; });
                    progressLabel.Invoke((MethodInvoker)delegate { progressLabel.Text = progressPercentage + " % - " + TraverseDirectoryFiles.filePathsCountIindex.ToString() + "/" + TraverseDirectoryFiles.totalFiles.ToString(); });

                }
            }

            TraverseDirectoryFiles.analyzeTaskFinished++;

            Logger.WriteLog("结束_分析线程_" + listIndex, "结束分析线程_" + listIndex);
        }
        /// <summary>
        /// 这是存储线程
        /// </summary>
        /// <param name="listIndex"></param>
        /// <param name="token"></param>
        private void StoreDataAsync(int listIndex, CancellationToken token)
        {
            Logger.WriteLog("开启_存储线程_" + listIndex, "开启存储线程_" + listIndex);
            Hashtable sqlHashtable = new Hashtable();

            while (!token.IsCancellationRequested)
            {
                if (TraverseDirectoryFiles.sqlHashtableQueue.TryDequeue(out sqlHashtable))
                {
                    TraverseDirectoryFiles.databaseProgress++;

                    // 执行SQL插入操作 
                    SqlServerHelper.ExecuteSqlTran(sqlHashtable);

                    // 更新数据库进度  
                    lock (TraverseDirectoryFiles.SyncRoot)
                    {
                        if (token.IsCancellationRequested)
                        {
                            break;
                        }

                        // 更新进度（进度条的范围是0-100）  
                        int progressPercentage = (int)((double)TraverseDirectoryFiles.databaseProgress / TraverseDirectoryFiles.databaseProgressTotal * 100);

                        if (progressPercentage > 100)
                        {
                            if (TraverseDirectoryFiles.databaseProgress > TraverseDirectoryFiles.databaseProgressTotal)
                            { TraverseDirectoryFiles.databaseProgress = TraverseDirectoryFiles.databaseProgressTotal; }
                            progressPercentage = 100;
                        }
                        progressBarDatabase.Invoke((MethodInvoker)delegate { progressBarDatabase.Value = progressPercentage; });
                        lbDatabase.Invoke((MethodInvoker)delegate { lbDatabase.Text = progressPercentage + " % - " + TraverseDirectoryFiles.databaseProgress.ToString() + "/" + TraverseDirectoryFiles.databaseProgressTotal.ToString(); });
                    }

                }

                if (TraverseDirectoryFiles.analyzeTaskFinished == TraverseDirectoryFiles.analyzeTaskCount && TraverseDirectoryFiles.sqlHashtableQueue.IsEmpty)
                {
                    Logger.WriteLog("结束_存储线程_" + listIndex, "结束存储线程_" + listIndex);
                    break;
                }
            }
        }

        #endregion

        private async void FormProgress_Load(object sender, EventArgs e)
        {
            #region 初始化表
            //************这句话是初始化表************ 
            SqlServerHelper.ExecuteSql("truncate table dt_iis_logs_analyzer;");
            //************这句话是初始化表************
            #endregion

            try
            {
                Logger.WriteLog("处理开始", "处理开始");
                TraverseDirectoryFiles.maxHascount = 200;
                TraverseDirectoryFiles.maxSqlcount = 200;
                TraverseDirectoryFiles.analyzeTaskCount = 5;
                TraverseDirectoryFiles.storeTasksCount = 3;
                // 调用方法获取分配的List  
                TraverseDirectoryFiles.distributedLists = Utils.DistributeListEvenly(TraverseDirectoryFiles.filePaths, TraverseDirectoryFiles.analyzeTaskCount);
                CancellationToken token = cancellationTokenSource.Token;

                isRunning = true;
                // 启动计时任务  
                Task timerTask = Task.Run(() => TimerCallback(token));

                // 初始化任务列表  
                List<Task> analyzeTasks = new List<Task>();
                List<Task> storeTasks = new List<Task>();

                // 使用循环启动分析任务  
                for (int i = 0; i < TraverseDirectoryFiles.analyzeTaskCount; i++)
                {
                    int currentI = i; // 捕获当前循环迭代的i值 
                    Task analyzeTask = Task.Run(() => EnqueueDataAsync(currentI, token), token);
                    analyzeTasks.Add(analyzeTask);
                }

                // 使用循环启动存储任务  
                for (int i = 0; i < TraverseDirectoryFiles.storeTasksCount; i++)
                {
                    int currentI = i; // 捕获当前循环迭代的i值 
                    Task storeTask = Task.Run(() => StoreDataAsync(currentI, token), token);
                    storeTasks.Add(storeTask);
                }

                allTasks.AddRange(analyzeTasks);
                allTasks.AddRange(storeTasks);

                try
                {
                    // 等待所有任务完成或抛出异常  
                    await Task.WhenAll(allTasks);
                    isRunning = false;

                    mainForm.BindDataBaseTotalMinMax();
                    mainForm.BindServer();
                    mainForm.BindDate();

                    Logger.WriteLog("处理结束", "处理结束");
                }
                catch (OperationCanceledException)
                {
                    Logger.WriteLog("任务被取消", "任务被取消。");
                }
                catch (AggregateException ae)
                {
                    // 处理异常，比如打印异常信息  
                    foreach (var innerException in ae.InnerExceptions)
                    {
                        Logger.WriteLog("异常信息", (innerException.Message));
                    }
                }
                catch (Exception ex)
                {
                    // 处理其他类型的异常                      
                    Logger.WriteLog("其他类型的异常", (ex.Message));
                }
                finally
                {
                    // 取消所有任务（如果尚未取消）  
                    cancellationTokenSource.Cancel();
                    // 等待所有任务完成，包括那些因取消而异常的任务  
                    try
                    {
                        await Task.WhenAll(allTasks);
                    }
                    catch { } // 忽略取消异常  

                    // 释放 CancellationTokenSource 资源  
                    cancellationTokenSource.Dispose();
                }

            }
            catch { }
        }

        private void FormProgress_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                // 取消所有任务  
                cancellationTokenSource.Cancel();
            }
            catch { }

            // 等待所有任务完成或抛出异常  
            try
            {
                Task.WhenAll(allTasks).Wait(); // 阻塞调用，等待所有任务完成  
            }
            catch (AggregateException ae)
            {
                // 处理异常，比如打印异常信息  
                foreach (var innerException in ae.InnerExceptions)
                {
                    Logger.WriteLog("关闭处理窗口异常信息", (innerException.Message));
                }
            }
            catch (OperationCanceledException)
            {
                // 处理取消情况  
                Logger.WriteLog("关闭处理窗口处理取消情况", "处理取消情况");
            }

            // 释放资源  
            cancellationTokenSource.Dispose();
            allTasks.Clear();
        }
    }
}
